﻿using System;
using System.Windows.Input;
using DataStore;
using DataStore.Domain;
using DataStore.Repositories;
using System.ComponentModel;
using Infrastructure.CurrentData;
using Microsoft.Practices.Composite.Events;

namespace Infrastructure.ViewModels
{
    /// <summary>
    /// ViewModel for category entity.
    /// </summary>
    public class CategoryViewModel : DataModelSingle<Category>, IDataErrorInfo
    {

        /// <summary>
        /// Initializes a new instance of the <see cref="CategoryViewModel"/> class.
        /// </summary>
        /// <param name="eventAggregator">The event aggregator.</param>
        /// <param name="category">The category entity.</param>
        public CategoryViewModel(IEventAggregator eventAggregator, Category category) : base(eventAggregator, category)
        {
            State = ModelState.Active;
        }

        /// <summary>
        /// Gets the category entity.
        /// </summary>
        /// <value>The category entity.</value>
        public Category Category
        {
            get
            {
                return Item;
            }
        }

        /// <summary>
        /// Gets or sets the id.
        /// </summary>
        /// <value>The id.</value>
        public virtual Guid Id 
        { 
            get
            {
                return Item.Id;
            }
            set
            {
                Item.Id = value;
                OnPropertyChanged("Id");
            }
        }
        /// <summary>
        /// Gets or sets the category text.
        /// </summary>
        /// <value>The text.</value>
        public virtual string Text
        {
            get
            {
                return Item.Text;
            } 
            set
            {
                Item.Text = value;
                OnPropertyChanged("Text");
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="CategoryViewModel"/> is selected.
        /// </summary>
        /// <value><c>true</c> if selected; otherwise, <c>false</c>.</value>
        public virtual bool Selected { get; set; }

        /// <summary>
        /// Gets the error message for the property with the given name.
        /// </summary>
        /// <returns>
        /// The error message for the property. The default is an empty string ("").
        /// </returns>
        /// <param name="columnName">The name of the property whose error message to get. </param>
        public string this[string columnName]
        {
            get
            {
                string error = string.Empty;
                error = (Item as IDataErrorInfo)[columnName];

                CommandManager.InvalidateRequerySuggested();
                return error;
            }
        }

        /// <summary>
        /// Gets an error message indicating what is wrong with this object.
        /// </summary>
        /// <returns>
        /// An error message indicating what is wrong with this object. The default is an empty string ("").
        /// </returns>
        public string Error
        {
            get { return (Item as IDataErrorInfo).Error; }
        }

        /// <summary>
        /// Gets a value indicating whether the category can be saved.
        /// </summary>
        /// <value><c>true</c> if this instance can save; otherwise, <c>false</c>.</value>
        protected override bool CanSave
        {
            get
            {
                return Item.IsValid; 
            }
        }

        /// <summary>
        /// Saves the category.
        /// </summary>
        public override void Save()
        {
            IDatabase database = Current.Container.Resolve<IDatabase>();
            using (var unitOfWork = database.CreateUnitOfWork())
            {
                try
                {
                    IRepository<Category> repository = new CategoryRepository(unitOfWork);
                    unitOfWork.BeginTransaction();
                    repository.SaveOrUpdate(Item);
                    unitOfWork.CommitTransaction();
                }
                catch
                {
                    unitOfWork.RollbackTransaction();
                    throw;
                }

            }
            base.Save();
            
        }

        /// <summary>
        /// Gets a value indicating whether the category is new item.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is new item; otherwise, <c>false</c>.
        /// </value>
        protected override bool IsNewItem
        {
            get { return Item.Id == Guid.Empty; }
        }
    }
}